package com.zhihesj.anan.security;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhihesj.anan.message.Message;
import com.zhihesj.anan.message.MessageCodeEnum;
import com.zhihesj.anan.system.entity.Logininfor;
import com.zhihesj.anan.system.service.LogininforService;
import com.zhihesj.anan.system.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;

/**
 * 登陆成功处理器
 * @author anan.
 * @version 1.0
 * @create 2020-04-22 09-42
 */
@Component
public class JwtAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private LogininforService logininforService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenUtil.generateToken(userDetails);
        renderToken(response,token);
        // 登陆成功后保存记录到数据库
        LoginVo loginVo=null;
        ObjectMapper mapper = new ObjectMapper();
        try (InputStream is = request.getInputStream()){
            loginVo = mapper.readValue(is, LoginVo.class);
        }catch (IOException e) {
            e.printStackTrace();
        }

        saveLoginLog(loginVo);
    }

    /**
     * 根据传入登陆信息，保存到数据库中
     * @param loginVo
     */
    private void saveLoginLog(LoginVo loginVo) {
        Logininfor logininfor=new Logininfor();
        logininfor.setBrowser(loginVo.getBrowser());
        logininfor.setIpaddr(loginVo.getLoginIp());
        logininfor.setLoginLocation(loginVo.getLoginLocation());
        logininfor.setLoginName(loginVo.getUsername());
        logininfor.setLoginTime(LocalDateTime.now());
        logininfor.setMsg(MessageCodeEnum.LOGIN_SUCCESS.getMessage());
        logininfor.setOs(loginVo.getOs());
        logininforService.save(logininfor);
    }

    /**
     * 渲染返回 token 页面,因为前端页面接收的都是Result对象，故使用application/json返回
     *
     * @param response
     * @throws IOException
     */
    public void renderToken(HttpServletResponse response,String token) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream out = response.getOutputStream();
        String str = JSONObject.toJSONString(Message.token(token));
        out.write(str.getBytes("UTF-8"));
        out.flush();
        out.close();
    }
}
